function C_callbackVideoIn(Src,Event,ID)
% CamTimer = timer('TimerFcn','tic;
% C_callbackVideoIn(CG.Sessions.Video(1).S,struct(''Type'',''Snapshot''),1); toc;','Period',0.5,'ExecutionMode','FixedDelay');
% C_callbackVideoIn(CG.Sessions.Video(1).S,[],1);

global CG;

% MOVE DATA TO INTERNAL VARIABLE
C_Logger('C_callbackVideoIn','Getting frame...\n');
LoggingState = get(Src,'Logging');

if strcmp(LoggingState,'on') && CG.Display.Video(ID).State
  LastFrame = peekdata(CG.Sessions.Video(ID).S,1);
  
  % KEEP TRACK OF TIME ETC
  CG.Sessions.Video(ID).Iteration = CG.Sessions.Video(ID).Iteration + 1;
  FramesAvailable = get(CG.Sessions.Video(ID).S,'FramesAvailable');
  
  % TRACK FRAMES
  LastFrames =  CG.Sessions.Video(ID).FramesAcquired;
  ThisFrames = FramesAvailable;
  CG.Sessions.Video(ID).FramesThisIteration = ThisFrames-LastFrames;
  CG.Sessions.Video(ID).FramesAcquired = ThisFrames;
  
  % TRACK TIME
  LastTime =  CG.Sessions.Video(ID).Time;
  ThisTime = datenum(Event.Data.AbsTime);
  CG.Sessions.Video(ID).TimeThisIteration = (ThisTime-LastTime)*(24*60*60);
  CG.Sessions.Video(ID).Time = ThisTime;
  
  %% CODE FOR GETTING DATA ONLINE
  %   cInd = CG.Sessions.Video(ID).FramesAcquired+1:CG.Sessions.Video(ID).FramesAcquired+FramesAvailable;
  %   if cInd(end) > size(CG.Data.Video(ID).Frames,4)
  %     CG.Data.Video(ID).Frames(end,end,1,end+1000) = 0;
  %      CG.Data.Video(ID).Time(end+1000) = 0;
  %   end
  %    if CG.Sessions.Video(ID).FramesAcquired > FramesAvailable
  %      LastTime = CG.Data.Video(ID).Time(CG.Sessions.Video(ID).FramesAcquired);
  %    else
  %      LastTime = 0;
  %    end
  %
  %   if FramesAvailable > 0
  %     [cFrames,cTime]  = getdata(CG.Sessions.Video(ID).S,FramesAvailable,'uint8');
  %    CG.Data.Video(ID).Frames(:,:,:,cInd) = cFrames;
  %    CG.Data.Video(ID).Time(cInd) = cTime;
  %    LastFrame = cFrames(:,:,:,end);
  %    CG.Sessions.Video(ID).FramesThisIteration = FramesAvailable;
  %    ThisTime = cTime(end);
  %    CG.Sessions.Video(ID).TimeThisIteration = ThisTime-LastTime;
  %   end
  
  if FramesAvailable
    LastFrame = flipud(squeeze(LastFrame(:,:,1,end))'); % ACCOUNT FOR ORIENTATION OF CAMERA
    
    % ESTIMATE FRONT OF ANIMAL POSITION
    % CG.Data.Video(ID).FrontPositionTime = CurrentTime;
    % DistProfile = mean(squeeze(LastFrame),1)/(2^8-1);
    % FrontPosition = find(DistProfile(end:-1:1)>CG.Sessions.Video(ID).BrightnessThreshold,1,'first');
    % if isempty(FrontPosition) || FrontPosition == 1 FrontPosition = NaN; end
    % CG.Data.Video(ID).FrontPosition(cIteration) = CG.Sessions.Video.Resolution(1)-FrontPosition;
    
    % UPDATE VIDEO DISPLAY
    if CG.Display.Video(ID).State  C_updateVideoDisplay(ID,LastFrame); end
    
    % DETECT EVENTS
    Events = {}; EventData = {};
    % PROCESS EVENTS
    for iE = 1:length(Events)     CG.Paradigm.processEvent('Source',{'Video',ID},'Event',{Events{iE},EventData{iE}});   end
  end
end